package com.heima.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.admin.utils.common.SensitiveWordUtil;
import com.heima.aliyun.GreenImageScan;
import com.heima.aliyun.GreenTextScan;
import com.heima.common.constants.message.PublishArticleConstants;
import com.heima.common.excpetion.CustException;
import com.heima.feign.admin.AdminFeign;
import com.heima.model.common.constants.wemedia.WemediaConstants;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.common.enums.AppHttpCodeEnum;
import com.heima.model.wemedia.pojos.WmNews;
import com.heima.wemedia.mapper.WmNewsAuditMapper;
import com.heima.wemedia.service.WmNewsAutoScanService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.AmqpException;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessagePostProcessor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;

import java.util.*;
import java.util.stream.Collectors;

/**
 * 自媒体文章自动审核类
 */
@Service("WmNewsAutoScanService")
@Slf4j
public class WmNewsAutoScanServiceImpl implements WmNewsAutoScanService {

    @Value("${file.oss.web-site}")
    String website;

    @Autowired
    private WmNewsAuditMapper wmNewsMapper;
    @Autowired
    RabbitTemplate rabbitTemplate;

    private String key = "_itcast_";

    /**
     * 自动审核
     *
     * @param id 自媒体文章id
     */
    @Override
    public boolean autoScanWmNews(Integer id) {
        if (id == null)
            CustException.cust(AppHttpCodeEnum.PARAM_INVALID, "文章Id为空,无法进行审核");
        boolean flag = false;

        WmNews wmNews = wmNewsMapper.selectById(id);
        if (wmNews == null)
            CustException.cust(AppHttpCodeEnum.DATA_NOT_EXIST, "没有找到这样的文章");

        if (wmNews.getStatus() != WmNews.Status.SUBMIT.getCode())
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "文章不处于待审核状态");

        //抽取文章中所有文本内容和图片内容
        Map<String, Object> map = this.handleTextAndImages(wmNews);

        //如果要审核的文章状态不为2
        if (wmNews.getStatus() == WmNews.Status.FAIL.getCode()) {
            return false;
        }
        //敏感词审核 失败 修改文章状态为2
        boolean sensitiveResult = this.handleSensitive((String) map.get("content"), wmNews);
        if (!sensitiveResult) {
            wmNews.setStatus(WmNews.Status.FAIL.getCode());
            wmNewsMapper.updateById(wmNews);
            return false;
        }
        //调用阿里云文本审核 失败2 不确定3
        boolean contentResult = this.handleTextScan((String) map.get("content"), wmNews);
        if (!contentResult) {
            wmNews.setStatus(WmNews.Status.FAIL.getCode());
            wmNewsMapper.updateById(wmNews);
            return false;
        }
        //调用阿里云图片审核 失败2 不确定3
        //判断图片集合是否为null
        Object images = map.get("images");
        if (images != null) {
            boolean imagesResult = this.handleImageScan((List<String>) images, wmNews);
            if (!imagesResult) {
                wmNewsMapper.updateById(wmNews);
                return false;
            }
        }

        wmNews.setStatus(WmNews.Status.SUCCESS.getCode());
        wmNews.setReason("审核成功");
        wmNewsMapper.updateById(wmNews);
        //发布文章
        WmNewsServiceImpl.pushNews(wmNews, rabbitTemplate);

        return true;
    }

    @Autowired
    GreenImageScan imagesScan;

    /**
     * 调用接口进行图片审核
     * true 为审核通过 false为审核失败
     */
    private boolean handleImageScan(List<String> images, WmNews wmNews) {
        boolean flag = true;
        try {
            //调用接口进行图片鉴定返回一个Map
            Map map = imagesScan.imageUrlScan(images);
            flag = handleScan(wmNews, true, map);

        } catch (Exception e) {
            e.printStackTrace();
            log.error("调用接口失败");
            // 转为人工审核
            wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
            wmNews.setReason("调用接口失败");
        }

        return flag;
    }

    @Autowired
    GreenTextScan textScan;

    /**
     * 调用接口进行文本审核
     * true 为审核通过 false为审核失败
     */
    private boolean handleTextScan(String source, WmNews wmNews) {
        boolean flag = true;
        try {
            Map map = textScan.greenTextScan(source);
            flag = handleScan(wmNews, true, map);
        } catch (Exception e) {
            log.error("调用接口失败");
            // 转为人工审核
            wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
            wmNews.setReason("调用接口失败");
        }
        return flag;
    }

    //解析接口返回结果进行文章状态设置
    private boolean handleScan(WmNews wmNews, boolean flag, Map map) {
        String suggestion = (String) map.get("suggestion");
        String label = (String) map.get("label");
        log.info("内容检测等级为:" + label);

        switch (suggestion) {
            case "block":
                // 内容违规
                wmNews.setStatus(WmNews.Status.FAIL.getCode());
                wmNews.setReason("自动审核失败");
                flag = false;
                break;
            case "review":
                // 不确定需要人工审核
                wmNews.setStatus(WmNews.Status.ADMIN_AUTH.getCode());
                wmNews.setReason("需要人工审核");
                flag = false;
                break;
        }
        return flag;
    }

    @Autowired
    AdminFeign adminFeign;

    @Value("${spring.redis.host}")
    String host;

    @Autowired
    RedisTemplate redisTemplate;

    /**
     * 调用本地敏感词列表进行敏感词过滤
     */
    private boolean handleSensitive(String content, WmNews wmNews) {
        boolean flag = true;

        //查询Redis中的敏感词列表
        Set<String> members = redisTemplate.opsForSet().members(WemediaConstants.SENSITIVE);
        //初始化敏感词Map
        SensitiveWordUtil.initMap(members);

        //对content进行敏感词检查 返回含有的敏感词Map
        Map<String, Integer> matchWords = SensitiveWordUtil.matchWords(content);
        if (matchWords.size() > 0) {
            //设置状态值为2 设置flag为false
            wmNews.setStatus(WmNews.Status.FAIL.getCode());
            flag = false;
        }

        return flag;
    }

    /**
     * 抽取文章所有文本内容和图片路径
     */
    private Map<String, Object> handleTextAndImages(WmNews wmNews) {
        String content = wmNews.getContent();

        if (content == null)
            CustException.cust(AppHttpCodeEnum.DATA_NOT_ALLOW, "文章内容不存在");

        //解析文章内容转为集合
        List<HashMap> array = JSON.parseArray(content, HashMap.class);

        //创建结果Map对象
        HashMap<String, Object> hashMap = new HashMap<>();

        //抽取文本内容
        String tests = array.stream().filter(key -> key
                        .get("type").equals("text"))
                .map(v -> (String) v.get("value"))
                .distinct()
                .collect(Collectors.joining(key));

        //将解析后的文本内容拼接标题
        content = tests + key + wmNews.getTitle();

        //抽取图片内容
        if (StringUtils.isNotBlank(wmNews.getImages())) {
            //用户上传了图片准备抽取
            List<String> images = array.stream().filter(key -> key
                            .get("type").equals("image"))
                    .map(v -> (String) v.get("value"))
                    .distinct()
                    .collect(Collectors.toList());

            //切割拼接图片路径
            List<String> collect = Arrays.stream(wmNews.getImages().split(","))
                    .distinct()
                    .map(u -> website + u)
                    .collect(Collectors.toList());

            images.addAll(collect);

            //去重
            images = images.stream().distinct().collect(Collectors.toList());

            hashMap.put("images", images);
        }

        hashMap.put("content", content);

        return hashMap;
    }
}
